#include <Wire.h>
#include <Adafruit_SHT4x.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiManager.h>

Adafruit_SHT4x sht4 = Adafruit_SHT4x();

// MQTT 配置
const char* mqtt_server = "qiaoyian.top";
const int mqtt_port = 11883;
const char* mqtt_user = "qiaodawei";
const char* mqtt_password = "qiao88588";

// 上报主题
const char* mqtt_topic_temp = "home/room1/temperature";
const char* mqtt_topic_hum = "home/room1/humidity";
const char* mqtt_topic_status = "home/room1/status";

// Home Assistant 自动发现主题
const char* ha_temp_config_topic = "homeassistant/sensor/esp8266_sht40_temperature/config";
const char* ha_hum_config_topic  = "homeassistant/sensor/esp8266_sht40_humidity/config";

WiFiClient espClient;
PubSubClient client(espClient);



void reconnect() {
  while (!client.connected()) {
    Serial.print("Connecting to MQTT...");
    if (client.connect("ESP8266Client", mqtt_user, mqtt_password, mqtt_topic_status, 1, true, "offline")) {
      Serial.println("connected");
      client.publish(mqtt_topic_status, "online", true); // 上线
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

// 发送 Home Assistant 自动发现消息
void sendHADiscovery() {
  String device_info = "{";
  device_info += "\"identifiers\": [\"esp8266_sht40\"],";
  device_info += "\"manufacturer\": \"ESP8266\",";
  device_info += "\"model\": \"SHT40 Sensor\",";
  device_info += "\"name\": \"Room Sensor\"";
  device_info += "}";

  // 温度传感器
  String temp_config = "{";
  temp_config += "\"name\": \"Room Temperature\",";
  temp_config += "\"unique_id\": \"esp8266_sht40_temperature\",";
  temp_config += "\"state_topic\": \""; temp_config += mqtt_topic_temp; temp_config += "\",";
  temp_config += "\"unit_of_measurement\": \"°C\",";
  temp_config += "\"device_class\": \"temperature\",";
  temp_config += "\"availability_topic\": \""; temp_config += mqtt_topic_status; temp_config += "\",";
  temp_config += "\"payload_available\": \"online\",";
  temp_config += "\"payload_not_available\": \"offline\",";
  temp_config += "\"device\": "; temp_config += device_info;
  temp_config += "}";
  client.publish(ha_temp_config_topic, temp_config.c_str(), true);

  // 湿度传感器
  String hum_config = "{";
  hum_config += "\"name\": \"Room Humidity\",";
  hum_config += "\"unique_id\": \"esp8266_sht40_humidity\",";
  hum_config += "\"state_topic\": \""; hum_config += mqtt_topic_hum; hum_config += "\",";
  hum_config += "\"unit_of_measurement\": \"%\",";
  hum_config += "\"device_class\": \"humidity\",";
  hum_config += "\"availability_topic\": \""; hum_config += mqtt_topic_status; hum_config += "\",";
  hum_config += "\"payload_available\": \"online\",";
  hum_config += "\"payload_not_available\": \"offline\",";
  hum_config += "\"device\": "; hum_config += device_info;
  hum_config += "}";
  client.publish(ha_hum_config_topic, hum_config.c_str(), true);

  Serial.println("Home Assistant discovery messages sent");
}

void setup() {
  Serial.begin(115200);
  Wire.begin();

  // Wi-Fi 自动配置
  WiFiManager wifiManager;
  wifiManager.autoConnect("ESP8266_Config");
  Serial.println("Connected to WiFi");

  // 初始化 SHT40
  if (!sht4.begin()) {
    Serial.println("Couldn't find SHT4x sensor!");
    while (1) delay(1);
  }

  // 初始化 MQTT
  client.setServer(mqtt_server, mqtt_port);

  reconnect();
  sendHADiscovery();

  // 发布上线状态
  client.publish(mqtt_topic_status, "online", true);
}

void loop() {
  if (!client.connected()) {
    reconnect();
    sendHADiscovery();
  }
  client.loop();

  sensors_event_t humidity, temp;
  sht4.getEvent(&humidity, &temp);

  float temperature = temp.temperature;
  float humidity_value = humidity.relative_humidity;

  Serial.print("Temperature: "); Serial.print(temperature); Serial.print(" C, ");
  Serial.print("Humidity: "); Serial.print(humidity_value); Serial.println(" %");

  client.publish(mqtt_topic_temp, String(temperature).c_str(), true);
  client.publish(mqtt_topic_hum, String(humidity_value).c_str(), true);

  delay(5000);
}
